package org.rambadger.command.axon;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.mongodb.Mongo;
import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;

/**
 * Holds configuration information of MongoDB and Axon
 */
public class MongoConfiguration {
    //This may get split into separate axon and mongo configuration classes.
    @JsonProperty @NotEmpty String host = "localhost";
    @JsonProperty @Min(1) @Max(65535) int port = 27017;
    @JsonProperty @NotEmpty String name;
    @JsonProperty @NotEmpty String eventCollection = "domain_events";
    @JsonProperty @NotEmpty String snapshotCollection = "snapshot_events";
    @JsonProperty @NotEmpty String sagaCollection = "sagas";
    @JsonProperty String username = null;
    @JsonProperty char[] password = null;

    /**
     * Gets hostname/address of the database.
     *
     * @return the address
     */
    public String getHost() {
        return host;
    }

    /**
     * Gets port number to connect to the database on.
     *
     * @return the port number
     */
    public int getPort() {
        return port;
    }

    /**
     * Gets the name of the database to use.
     *
     * @return the database name
     */
    public String getDatabaseName() {
        return name;
    }

    /**
     * Gets name of the collection to store axon's domain evetns in.
     *
     * @return the name of the collection for storing domain events
     */
    public String getEventCollection() {
        return eventCollection;
    }

    /**
     * Gets the name of the collection that axon uses to store snapshots.
     *
     * @return the name collection that snapshots are stored in
     */
    public String getSnapshotCollection() {
        return snapshotCollection;
    }

    /**
     * Gets the name of the collection that axon uses to store sagas
     *
     * @return the name collection that sagas are stored in
     */
    public String getSagaCollection() {
        return sagaCollection;
    }

    /**
     * Gets the optional username used to authenticate with the database.
     *
     * @return the database username
     */
    public String getUsername() {
        return username;
    }

    /**
     * Gets the optional password used to authenticate with the database.
     *
     * @return the database password
     */
    public char[] getPassword() {
        return password;
    }

    /**
     * Creates the {@link org.axonframework.eventstore.mongo.MongoTemplate MongoTemplate} used for the event store
     *
     * @param mongo the {@link Mongo} instance
     * @return the mongo template
     */
    public org.axonframework.eventstore.mongo.MongoTemplate getMongoEventTemplate(Mongo mongo) {
        return new org.axonframework.eventstore.mongo.DefaultMongoTemplate(mongo, getDatabaseName(), eventCollection, snapshotCollection, username, password);
    }

    /**
     * reates the {@link org.axonframework.saga.repository.mongo.MongoTemplate MongoTemplate} used for the saga repository
     *
     * @param mongo the {@link Mongo} instance
     * @return the mongo  template
     */
    public org.axonframework.saga.repository.mongo.MongoTemplate getMongoSagaTemplate(Mongo mongo) {
        return new org.axonframework.saga.repository.mongo.DefaultMongoTemplate(mongo, getDatabaseName(), sagaCollection, username, password);
    }
}
